
export interface TextPosition {
    line: number;
    character: number;
}

export interface TextRange {
    start: TextPosition;
    end: TextPosition;
}

export interface LocalLanguage {
    readonly shortCode: string;
    readonly longCode: string;
    readonly label: string;
}

export const _defaultLanguage: LocalLanguage = { longCode: "zh-cn"   , shortCode: "CHS", label: "Chinese - China", };

export interface Disposable {
    dispose(): any;
}

export interface Action<P> {
    (arg: P): void;
}

export interface Func<P, R> {
    (arg: P): R;
}

export interface EventHandler<T, P, R = void> {
    (sender: T, args: P): R;
}

export interface Event<T, P, R = void> {
    (listener: EventHandler<T, P>, thisArg?: any): R;
}

export interface MapLike<T> {
    [key: string]: T;
}

export type Logger = Func<string, void>;

export type Mutable<T extends object> = { -readonly [K in keyof T]: T[K] };

export type LineFeedCharater = "\r\n" | "\n";

export interface ScriptOptions {
    defaultMetadataLanguage: LocalLanguage;
    defaultMetadataContext: number;
    defaultMetadataLabelType: number;
    userName: string;
}

export type ScriptOptionUpdateParam = { [K in keyof ScriptOptions]?: ScriptOptions[K] };

export interface MDMSerializerOptions {
    indentSpaceCount: number;
    lineFeedCharater: LineFeedCharater;
    invalidValueUpperBoundary: number;
    invalidValueLowerBoundary: number;
    hideLabeledObjectProperties: boolean;
}

export interface MDMLoaderOptions {
    mdmVersion: string;
    invalidValueUpperBoundary: number;
    invalidValueLowerBoundary: number;
    defaultLanguage: LocalLanguage;
    defaultContext: string;
    defaultLabelType: string;
    defaultRoutingContext: string;
    defaultScriptType: string;
    userName: string;
    checkAliasConflict: boolean;
}

export interface DsWorkspaceProperties {
    'metadata'?: string;
    'mdmSerializer.indentSpaceCount': number;
    'mdmSerializer.lineFeedCharater': string;
}

export interface DsSerializerProperties {
    // 全局配置
    'mdmSerializer.invalidValueUpperBoundary': number;
    'mdmSerializer.invalidValueLowerBoundary': number;
    'mdmSerializer.hideLabeledObjectProperties': boolean;
}

export interface DsLoaderProperties {
    'mdmLoader.mdmVersion': string;
    'mdmLoader.invalidValueUpperBoundary': number;
    'mdmLoader.invalidValueLowerBoundary': number;
    'mdmLoader.defaultLanguage': string;
    'mdmLoader.defaultContext': string;
    'mdmLoader.defaultLabelType': string;
    'mdmLoader.defaultRoutingContext': string;
    'mdmLoader.defaultScriptType': string;
    'mdmLoader.checkAliasConflict': boolean;
}

export interface DsWindowProperties {
    'workspaceFolderNames': string;
    'userName': string;
    'codeFolding': boolean;
    'metadataContext': string;
    'metadataLanguage': string;
    'metadataLabelType': string;
    'promptMetadataWhenOpenFile': boolean;
    'closeMddAfterSerialization': boolean;
}

export interface DsProperties extends DsWindowProperties, DsWorkspaceProperties, DsSerializerProperties, DsLoaderProperties {
}

export interface OpenDialogOptions {
    defaultPath?: string;
    openLabel?: string;
    canSelectMany?: boolean;
    filters?: { [name: string]: string[] };
    title?: string;
}

export interface QuickPickOptions {
    folder: string;
    extens: string[];
    files?: string[];
}

export type DsWindowPropertiesUpdateParams = { [K in keyof DsWindowProperties]?: DsWindowProperties[K] };

export interface DsWorkspacePropertiesUpdateParams {
    rootPath: string;
    properties: { [K in keyof DsWorkspaceProperties]?: DsWorkspaceProperties[K] };
}

export interface GetConfigurationHandler<T> {
    (root: string): T;
}

export interface SelectFileBranchParams {
    fsPath: string;
    selectBranch: string;
}

export interface SetProgramMetadataParams {
    uri: string;
    metadata: string;
}

export namespace DefaultOptions {

    export const workspaceFolderNames: string[] = [ "dpgm" ];

    const userName = process.env["USERNAME"]!;
    const invalidValueLowerBoundary = -2147483648;
    const invalidValueUpperBoundary = 2147483647;

    export const codeFolding = true;
    export const metadataContext = "Question";
    export const metadataLanguage = _defaultLanguage;
    export const metadataLabelType = "Label";
    export const metadataRoutingContext = "Paper";
    export const metadataScriptType = "mrScriptBasic";
    export const promptMetadataWhenOpenFile = true;
    export const closeMddAfterSerialization = true;

    export const scriptOptions: ScriptOptions = {
        defaultMetadataLanguage: _defaultLanguage,
        defaultMetadataContext: 0,
        defaultMetadataLabelType: 0,
        userName,
    };

    export const mdmSerializerOptions: MDMSerializerOptions = {
        indentSpaceCount: 4,
        lineFeedCharater: "\r\n",
        invalidValueLowerBoundary,
        invalidValueUpperBoundary,
        hideLabeledObjectProperties: false,
    };

    export const mdmLoaderOptions: MDMLoaderOptions = {
        mdmVersion: "6.0.1.1.60",
        invalidValueLowerBoundary,
        invalidValueUpperBoundary,
        defaultLanguage: metadataLanguage,
        defaultContext: metadataContext,
        defaultLabelType: metadataLabelType,
        defaultRoutingContext: metadataRoutingContext,
        defaultScriptType: metadataScriptType,
        checkAliasConflict: true,
        userName,
    };

}

export const enum LanguageRequests {
    getWindowConfiguration = "dsclient/getWindowConfiguration",
    getConfiguration = "dsclient/getConfiguration",
    showOpenFileDialog = "dsclient/showOpenFileDialog",
    showQuickPickFile = "dsclient/showQuickPickFile",
    getFileCurrentBranch = "dsclient/getFileCurrentBranch",
    getFileBranches = "dsclient/getFileBranches",
    selectFileBranch = "dsclient/selectFileBranch",
    getProgramMetadata = "dsclient/getProgramMetadata",
    setProgramMetadata = "dsclient/setProgramMetadata",
}

export const enum LanguageNotifications {
    showEditor = "dsclient/showEditor",
    closeActivateEditor = "dsclient/closeActivateEditor",
    initializeServerWindowConfigurations = "dsclient/initializeServerWindowConfigurations",
    configurationChanged = "dsclient/configurationChanged",
    workspaceConfigurationChanged = "dsclient/workspaceConfigurationChanged",
}

export const enum LanguageCommand {
    selectFileBranchCommand = "dsclient.selectFileBranch",
    selectProgramMetadata = "dsclient.selectProgramMetadata",
}

export interface SemanticToken {
    line: number;
    character: number;
    length: number;
}

export interface GetSemanticTokensResult {
    tokens: SemanticToken[];
}

export interface RequestDocumentIdentifier {
    uri: string;
    fsPath: string;
}

export interface RequestCompletionParam extends RequestDocumentIdentifier {
    position: number;
    triggerCharacter: string | undefined;
}

export interface RequestHoverParam extends RequestDocumentIdentifier {
    position: number;
}

export interface RequestDefinitionParam extends RequestDocumentIdentifier {
    position: number;
}

export interface RequestReferenceParam extends RequestDocumentIdentifier {
    position: number;
    includeDefinition: boolean;
}

export interface RequestSignatureHelpParam extends RequestDocumentIdentifier {
    position: number;
    triggerKind: number;
    triggerCharacter: string | undefined;
    isReTrigger: boolean;
}

export interface RequestRenameParam extends RequestDocumentIdentifier {
    position: number;
}

export interface RequestRenameResult {
    canRename: boolean;
    triggerLocation: TextRange;
    changes: { [uri: string]: TextRange[] };
    errorMessage?: string;
}
